// © 2016 and later: Unicode, Inc. and others.
// License & terms of use: http://www.unicode.org/copyright.html
/*
 *******************************************************************************
 * Copyright (C) 2007-2011, International Business Machines Corporation and    *
 * others. All Rights Reserved.                                                *
 *******************************************************************************
 */
package com.ibm.icu.dev.demo;

import com.ibm.icu.dev.demo.impl.DemoApplet;
import com.ibm.icu.dev.demo.impl.DemoUtility;
import com.ibm.icu.util.VersionInfo;
import java.awt.BorderLayout;
import java.awt.Button;
import java.awt.Color;
import java.awt.Frame;
import java.awt.GridLayout;
import java.awt.Label;
import java.awt.Panel;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.List;

/**
 * @author srl Application to provide a panel of demos to launch
 */
public class Launcher extends DemoApplet {
    private static final long serialVersionUID = -8054963875776183877L;

    /** base package of all demos */
    public static final String demoBase = "com.ibm.icu.dev.demo";

    /** list of classes, relative to the demoBase. all must have a static void main(String[]) */
    public static final List<String> demoList =
            List.of(
                    "calendar.CalendarApp",
                    "charsetdet.DetectingViewer",
                    "holiday.HolidayCalendarDemo",
                    "rbnf.RbnfDemo",
                    "translit.Demo");

    public class LauncherFrame extends Frame implements ActionListener {
        private static final long serialVersionUID = -8054963875776183878L;

        public Button buttonList[] = new Button[demoList.size()]; // one button for each demo
        public Label statusLabel;
        private DemoApplet applet;

        LauncherFrame(DemoApplet applet) {
            init();
            this.applet = applet;
        }

        public void init() {
            // close down when close is clicked.
            // TODO: this should be factored..
            addWindowListener(
                    new WindowAdapter() {
                        public void windowClosing(WindowEvent e) {
                            setVisible(false);
                            dispose();

                            if (applet != null) {
                                applet.demoClosed();
                            } else System.exit(0);
                        }
                    });

            setBackground(DemoUtility.bgColor);
            setLayout(new BorderLayout());

            Panel topPanel = new Panel();
            topPanel.setLayout(new GridLayout(5, 3));

            for (int i = 0; i < buttonList.length; i++) {
                String demo = demoList.get(i);
                Button b = new Button(demo);
                b.addActionListener(this);
                buttonList[i] = b;
                topPanel.add(b);
            }
            add(BorderLayout.CENTER, topPanel);
            statusLabel = new Label("");
            statusLabel.setAlignment(Label.LEFT);
            String javaVersion = "";
            try {
                javaVersion = "* Java: " + System.getProperty("java.version");
            } catch (Throwable t) {
                javaVersion = "";
            }
            add(
                    BorderLayout.NORTH,
                    new Label(
                            "ICU Demos * ICU version "
                                    + VersionInfo.ICU_VERSION
                                    + " * https://icu.unicode.org/ "
                                    + javaVersion));
            add(BorderLayout.SOUTH, statusLabel);
            // set up an initial status.
            showStatus(buttonList.length + " demos ready. ");
        }

        /**
         * Change the 'status' field, and set it to black
         *
         * @param status
         */
        void showStatus(String status) {
            statusLabel.setText(status);
            statusLabel.setForeground(Color.BLACK);
            statusLabel.setBackground(Color.WHITE);
            //            statusLabel.setFont(Font.PLAIN);
            doLayout();
        }

        void showStatus(String demo, String status) {
            showStatus(demo + ": " + status);
        }

        void showFailure(String status) {
            statusLabel.setText(status);
            statusLabel.setBackground(Color.GRAY);
            statusLabel.setForeground(Color.RED);
            //            statusLabel.setFont(Font.BOLD);
            doLayout();
        }

        void showFailure(String demo, String status) {
            showFailure(demo + ": " + status);
        }

        public void actionPerformed(ActionEvent e) {
            // find button
            for (int i = 0; i < buttonList.length; i++) {
                if (e.getSource() == buttonList[i]) {
                    String demoShort = demoList.get(i);
                    String demo = demoBase + '.' + demoShort;
                    showStatus(demoShort, "launching");
                    try {
                        Class c = Class.forName(demo);
                        String args[] = new String[0];
                        Class params[] = new Class[1];
                        params[0] = args.getClass();
                        Method m = c.getMethod("main", params);
                        Object[] argList = {args};
                        m.invoke(null, argList);
                        showStatus(demoShort, "launched.");
                    } catch (ClassNotFoundException e1) {
                        showFailure(demoShort, e1.toString());
                        e1.printStackTrace();
                    } catch (SecurityException se) {
                        showFailure(demoShort, se.toString());
                        se.printStackTrace();
                    } catch (NoSuchMethodException nsme) {
                        showFailure(demoShort, nsme.toString());
                        nsme.printStackTrace();
                    } catch (IllegalArgumentException iae) {
                        showFailure(demoShort, iae.toString());
                        iae.printStackTrace();
                    } catch (IllegalAccessException iae) {
                        showFailure(demoShort, iae.toString());
                        iae.printStackTrace();
                    } catch (InvocationTargetException ite) {
                        showFailure(demoShort, ite.toString());
                        ite.printStackTrace();
                    }
                    repaint();
                }
            }
        }
    }

    /* This creates a Frame for the demo applet. */
    protected Frame createDemoFrame(DemoApplet applet) {
        return new LauncherFrame(applet);
    }

    /**
     * The main function which defines the behavior of the Demo applet when an applet is started.
     */
    public static void main(String[] args) {
        new Launcher().showDemo();
    }
}
